home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Frameworks / Grant's CGI Framework 1.0b12 / Util / ProcessUtil.c < prev    next >
Text File  |  1995-12-09  |  5KB  |  213 lines

  1. /*****
  2.  *
  3.  *    ProcessUtil.c
  4.  *
  5.  *    This is a support file for "Grant's CGI Framework".
  6.  *    Please see the license agreement that accompanies the distribution package
  7.  *    for licensing details.
  8.  *
  9.  *    Copyright ©1995 by Grant Neufeld
  10.  *    grant@acm.com
  11.  *    http://arpp1.carleton.ca/grant/
  12.  *
  13.  *****/
  14.  
  15. #include "MyConfiguration.h"
  16.  
  17. #include <Threads.h>
  18.  
  19. #include "compiler_stuff.h"
  20. #include "globals.h"
  21.  
  22. #include "DebugUtil.h"
  23.  
  24. #include "ProcessUtil.h"
  25.  
  26.  
  27. /***  LOCAL PROTOTYPES  ***/
  28.  
  29. pascal void        myThreadTermination    ( ThreadID, void * );
  30.  
  31.  
  32. /***  FUNCTIONS  ***/
  33.  
  34. /* Determine if the current application is active (is in front of all others) */
  35. Boolean
  36. ProcessCurrentIsFront ( void )
  37. {
  38.     #if kCompileWithForeground
  39.     
  40.     Boolean                    isFront;
  41.     ProcessSerialNumber        myPSN;
  42.     OSErr                    theErr;
  43.     
  44.     /* get my process serial number. IM:Processes 2-21 */
  45.     theErr = GetCurrentProcess ( &myPSN );
  46.     
  47.     if ( theErr != noErr )
  48.     {
  49.         /* might want to do something else here to handle the error */
  50.         return false;
  51.     }
  52.     
  53.     isFront = ProcessIsFront ( &myPSN );
  54.     
  55.     return isFront;
  56.     
  57.     #else    /* if not kCompileWithForeground */
  58.     
  59.     return false;
  60.     
  61.     #endif    /* kCompileWithForeground */
  62. } /* ProcessCurrentIsFront */
  63.  
  64.  
  65. /* Determine if the specified application is active (is in front of all others) */
  66. Boolean
  67. ProcessIsFront ( ProcessSerialNumber *thePSN )
  68. {
  69.     OSErr                    theErr;
  70.     ProcessSerialNumber        frontPSN;
  71.     
  72.     my_assert ( thePSN != nil, "\pProcessIsFront: thePSN ptr is nil" );
  73.     
  74.     theErr = GetFrontProcess ( &frontPSN );
  75.     
  76.     if ( theErr != noErr )
  77.     {
  78.         /* might want to do something else here to handle the error */
  79.         return false;
  80.     }
  81.     
  82.     return ( (frontPSN.lowLongOfPSN == thePSN->lowLongOfPSN) &&
  83.         (frontPSN.highLongOfPSN == thePSN->highLongOfPSN) );
  84. } /* ProcessIsFront */
  85.  
  86.  
  87. /* Fill out an already allocated FSSpec with the current process' location.
  88.     Thanks to Gregory S. Combs for providing most of this function. */
  89. OSErr
  90. ProcessGetMyFSSpec ( FSSpec *procFileSpec )
  91. {
  92.     OSErr                    theErr;
  93.     ProcessSerialNumber        curPSN;
  94.     ProcessInfoRec            procInfo;
  95.     Str255                    appName;
  96.     
  97.     my_assert ( procFileSpec != nil, "\pProcessGetMyFSSpec: procFileSpec ptr is nil" );
  98.     
  99.     theErr = GetCurrentProcess ( &curPSN );
  100.     
  101.     if ( theErr == noErr )
  102.     {
  103.         procInfo.processInfoLength    = sizeof ( ProcessInfoRec );
  104.         procInfo.processName        = appName;
  105.         procInfo.processAppSpec        = procFileSpec;
  106.         
  107.         theErr = GetProcessInformation ( &curPSN, &procInfo );
  108.     }
  109.     
  110.     return theErr;
  111. } /* ProcessGetMyFSSpec */
  112.  
  113.  
  114. /**  THREAD FUNCTIONS  **/
  115. #pragma mark -
  116.  
  117. /* Allocate a new thread from the existing pool of threads.
  118.     If there are no threads available, yield to other threads until one finishes. */
  119. OSErr
  120. MyNewThreadFromPool (
  121.     ThreadEntryProcPtr    threadEntry,
  122.     void *                threadParam,
  123.     void **                threadResult,
  124.     ThreadID *            threadMade )
  125. {
  126.     OSErr    theErr;
  127.     short    threadsFree;
  128.     
  129.     #if kCompileWithThreadsOptional
  130.     my_assert ( gHasThreadMgr, "\pMyNewThreadFromPool: Thread Manager not available" );
  131.     #endif
  132.     
  133.     theErr = GetFreeThreadCount ( kCooperativeThread, &threadsFree );
  134.     
  135.     /* while there is no error, and there are no threads free, */
  136.     while ( (theErr == noErr) && (threadsFree <= nil) )
  137.     {
  138.         /* give other threads a chance to complete */
  139.         YieldToAnyThread ();
  140.         
  141.         /* check if any other threads did complete */
  142.         theErr = GetFreeThreadCount ( kCooperativeThread, &threadsFree );
  143.     }
  144.     
  145.     if ( theErr == noErr )
  146.     {
  147.         /* install the new thread using a premade thread */
  148.         theErr = NewThread ( kCooperativeThread, threadEntry, threadParam, nil,
  149.             kFPUNotNeeded + kUsePremadeThread, threadResult, threadMade );
  150.     }
  151.     
  152.     if ( theErr == noErr )
  153.     {
  154.         /* set the termination function for the thread */
  155.         SetThreadTerminator ( *threadMade, myThreadTermination, nil );
  156.         
  157.         /* increment the total number of sub-threads */
  158.         ++gThreadTotal;
  159.     }
  160.     
  161.     return theErr;
  162. } /* MyNewThreadFromPool */
  163.  
  164.  
  165. /*  */
  166. pascal void
  167. myThreadTermination ( ThreadID threadTerminated, void *terminationProcParam )
  168. {
  169.     #if kCompileWithThreadsOptional
  170.     my_assert ( gHasThreadMgr, "\pmyThreadTermination: Thread Manager not available" );
  171.     #endif
  172.     
  173.     /* Lower the count of sub-threads */
  174.     --gThreadTotal;
  175. } /* myThreadTermination */
  176.  
  177.  
  178. /* Give all sub-threads a chance to finish */
  179. void
  180. ThreadFinishAllSubThreads ( void )
  181. {
  182.     ThreadID    currentThread;
  183.     
  184.     #if kCompileWithThreadsOptional
  185.     my_assert ( gHasThreadMgr, "\pThreadFinishAllSubThreads: Thread Manager not available" );
  186.     #endif
  187.     
  188.     GetCurrentThread ( ¤tThread );
  189.     
  190.     if ( currentThread != gThreadMain )
  191.     {
  192.         /* lower the count of sub-threads to prevent this sub-thread from
  193.             preventing the exit of the while loop below */
  194.         --gThreadTotal;
  195.     }
  196.     
  197.     while ( gThreadTotal > nil )
  198.     {
  199.         /* while there remain other threads (not including the current and main),
  200.             let them finish before quitting */
  201.         YieldToAnyThread ();
  202.     }
  203.     
  204.     if ( currentThread != gThreadMain )
  205.     {
  206.         /* increase the count of sub-threads */
  207.         ++gThreadTotal;
  208.     }
  209. } /* ThreadFinishAllSubThreads */
  210.  
  211.  
  212. /*****  EOF  *****/
  213.